Element-Ui 实践

2020.6.17 星期三 17:03

基础

  1. 可以按需引入,也可以全部引入

  2. 改变/自定义 element ui 样式:需要在全局中修改(style标签不加 scoped),比如 .el-carousel__button, 或者单独引入css文件,即使是在本模块import; 添加className 提高权重,即使!import 也不会生效(如果样式不是全局的话).
    $PS:听说可以在style中添加!import, html标签都找不到,往哪个元素上添加.自述比较麻烦
    $PS:有的样式好像可以在scoped中修改,比如.el-main,.el-col-6,或许因为这些是layout样式?

$TODO: 样式引入方式/权重 分析.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* <!--  <style scoped>: worked --> */
.el-col-6{
padding:0 10px;
}
.el-main{
padding:0;
}

/* <!-- <style scoped>: not work --> */
.self .el-carousel__button{ /* not work */
border-radius:50%;
background:##ff0!important;
}
.el-carousel__button{ /* not work */
border-radius:30%;
background:##f00!important;
}

  1. 自定义主题。可以在网站设置每个具体组件的大小,样式等;包括主要的颜色主题等。
    或者文档其他自定义变量方式等。
    还动态切换主题色。

el-form

数据类型:v-model 可以指定数据类型。比如 v-model.number = "numb1"

注意这里为 v-model attribute 添加了 .number。它会告诉 Vue 将其值作为数字来使用。不过这里有一个小小的 bug,那就是当其值为空的时候,它会回到字符串格式,
事件:对于elementUI的input,我们需要在后面加上.native, 因为elementUI对input进行了封装,原生的事件不起作用。
<!–
视图更新:下拉多选 和 时间范围选择 编辑的时候,点击修改视图不会更新 // – 而是修改其他一个东西:比如输入框,单选的时候,多选只更新了最后的操作
下拉多选<el-select v-model="form_base.grades" @change="$forceUpdate()" multiple placeholder="请选择" style="width: 100%">
或者this.subscribeData.splice();,this.$set() // 并没有实际,应该是可以的。必forceUpdate 更好一些
时间范围选择@blur="handleTimestamp" // @change 并没有触发
源码中,为什么是blur才行:date-picker组件内监听picker显示隐藏属性里拉起blur函数,但未拉起change函数。

上面问题的原因是初始化的时候直接赋值this.form_base.grades = [],没有走vue的数据绑定。
正确的方式this.form_base = { title: '', grades: []} 或者this.$set(this.form_base, 'grades', [])
–>

el-form-item

  1. 自定义label 标签 <span slot="label">自己写label </span>

    表单验证

  2. el-form validate方法组织程序后续流程
    原因:自己写的validate 没有调用callback()
  3. validate() 用asycn/await 拿不到结果。需要在回调中赋值
    1
    2
    3
    let valid
    await this.$refs.r_form_base.validate(r => valid = r)
    if(!valid) return this.$message.warning('当前内容设置未完成')

select

后台返回数据为0(为选择),如果options 中没有,会显示没有的id。
解决:可以手动添加一行(for 循环外)为0的情况。<el-option label="请选择" :value="0"></el-option>
同理提交的时候,可以默认值为0,而不是空字符串。 (后端强类型,一定要)
<!–
但是:上面添加的请选择就成为了一个选项 出现在了 下拉选择列表中了。
并不想要,只好再改回去。手动修改数据了。

也不能把‘请选择’ 换为‘全部’。因为这里就是 请选择。
最后,筛选区可以把placeholder 改成 ‘全部’。
提交的时候也可以是0(需要和后端统一)
–>

tree

  1. 手动展开/收起 全部。
    :default-expand-all="treeExpand" 只能设置默认状态。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    expandAll(bool) {
    var nodes = this.$refs.ProjectTree.store.nodesMap;
    for (var i in nodes) {
    nodes[i].expanded = bool;
    }
    // 或者
    for(var i=0;i<this.$refs.tree.store._getAllNodes().length;i++){
    this.$refs.tree.store._getAllNodes()[i].expanded=this.isexpand;
    }
    }
  2. props:curr-course-id 变化并不会引起css高亮。 #/17246
    需要监听变化,然后调用api:setCurrentKey。或者

    1
    2
    3
      this.$refs.tree.store.nodesMap[oldValue].isCurrent = false;
    this.$refs.tree.store.nodesMap[value].isCurrent = true;
    `
  3. 取消高亮的时候,不能通过设置currentKey,需要先获取currKey,调用上面的api修改tree.store

    1
    2
    3
    4
    5
    // this.currCourseId = '';
    // this.$refs.courseTree.$refs.tree.setCurrentKey('');
    // 高亮并不会被取消,需要如下调用
    const currKey = this.$refs.courseTree.$refs.tree.getCurrentKey();
    this.$refs.courseTree.$refs.tree.store.nodesMap[currKey].isCurrent = false;
  4. 树 会把叶子节点也展示出来,也就是说不是一个文件夹结构,文件也会出现在层级。
    如果业务只需要展示文件夹目录,而且前面的小三角icon 也不需要显示。
    两种方式:1)重新格式化(后端)返回的数据结构;2)调用 tree的相关api 进行数据和ui 的展示。

  5. 如果数据源发生变化,要调用filter方法,需要在nextTick 中。
1
2
3
4
5
6
7
8
<div class="sidebar-course">
<!-- <h3>课程管理</h3> -->
<course-tree ref="courseTree" :course-data="courseTreeData"
:curr-course-id="currCourseId" :expand-course-id="expandCourseId"
@courseDirClick="changeCourseViewData"
/>
</div>
<!-- End: 课程管理 -->
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
<!--
* @title: 课件包切换/选择
* @desc: 左侧边栏课件包选择
* @date: 20200604
-->
<template>
<div class="course-tree">
<!-- <el-input placeholder="输入关键字进行过滤" v-model.trim="filterText" size="small"
style="width:80%;"
@input="filterCoureseName"
v-if="false"
>
</el-input> -->
<el-tree ref="tree" :data="courseData" :props="defaultProps" empty-text="没有设置名称"
node-key="id" :current-node-key.sync="currCourseId"
:default-expanded-keys="expandCourseId"
:highlight-current="true" :expand-on-click-node="false" :check-on-click-node="true"
:lazy="true"
:load="loadNode"
@node-click="handleNodeClick"
:filter-node-method="filterNode"
@current-change="handleCurrNodeChange"
>
<span :class="['custom-tree-node', `custom-tree-node-${data.type}`]" slot-scope="{ node, data }">
{{ node.label }} {{ node.level }}
</span>
</el-tree>
</div>
</template>

<script>

export default {
name: 'CourseTree',
components: {},
props: {
courseData: {
type: Array,
default: () => [],
},
currCourseId: {
type: String,
default: ''
},
expandCourseId: {
type: Array,
default: () => [],
}
},
data() {
return {
filterText: '',
defaultProps: {
children: 'children',
label: 'label',
isLeaf: (data, node) => {
// console.log('is leaf. node', data, node);
return !data.children || !data.children.some(v => v.type !== 'courseware');
},
},
};
},
computed: {
},
watch: {
currCourseId(value, oldValue) {
this.$refs.tree.setCurrentKey(value);
// this.$refs.tree.store.nodesMap[oldValue].isCurrent = false;
// this.$refs.tree.store.nodesMap[value].isCurrent = true;
},
courseData() {
// console.log('watch course data');
this.$nextTick(() => {
this.$refs.tree.filter(); // 把课程子节点过滤掉
});
}
},
mounted() {
// this.$refs.tree.filter();
// setTimeout(() => this.$refs.tree.filter(), 200);
},
methods: {
filterCoureseName(value) {
this.$refs.tree.filter(value);
},
filterNode(value, data) {
// console.log('filter node.', value, data);
const isShow = data.type !== 'courseware';
if (!value) return isShow;
return isShow && data.label.includes(value);
},
loadNode(node, resolve) {
// console.log('load node.', node);
if (node.level === 0) {
return resolve(node.data);
}
const treeNode = node.data.children.filter(v => v.type !== 'courseware');
// node.data.children = treeNode; // 必须修改源node,否则项目切换时不会过滤掉课件;还要调用filter
return resolve(treeNode);
},
/* eslint-disable no-unused-vars */
handleNodeClick(obj, node, comp) {
// console.log(obj, node, comp);
this.$emit('courseDirClick', obj);
},
handleCurrNodeChange(obj) {
// console.log('current node changed.', obj);
},
},
};
const _data = [{
id: '-',
label: '课程管理',
children: [
{
id: '1',
label: '大班',
children: [
{
id: '1-1',
label: '大班-1周',
children: [
{ id: '', type: 'courseware', label: '1-1-课件1', updated: '2020.6.4 12:00', },
{ id: '', type: 'courseware', label: '1-1-课件1', updated: '2020.6.4 13:00' },
{ id: '', type: 'courseware', label: '1-1-课件2', updated: '2020.6.4 13:00' },
{ id: '', type: 'courseware', label: '1-1-课件3', updated: '2020.6.4 13:00' },
],
},
{
id: '1-2',
label: '大班-2周',
children: [
{
id: '1-2-1',
label: '大班-2周(1)',
children: [
{ id: '', type: 'courseware', status: 1, resources: [], label: '1-2(1)-课件1', updated: '2020.6.4 12:00', },
{ id: '', type: 'courseware', status: 2, resources: [2, 4], label: '1-2(1)-课件1', updated: '2020.6.4 13:00' },
{ id: '', type: 'courseware', status: 0, resources: [], label: '1-2(1)-课件1', updated: '2020.6.4 13:00' },
{ id: '', type: 'courseware', status: 3, resources: [1, 2, 3, 4], label: '1-2(1)-课件2', updated: '2020.6.4 13:00' },
{ id: '', type: 'courseware', status: 4, resources: [], label: '1-2(1)-课件3', updated: '2020.6.4 13:00' },
]
},
],
},
{id: 'c1', type: 'courseware', label: '待定课件1', updated: '2020 14:00', status: 1, thumbnail: 'http://t8.baidu.com/it/u=1484500186,1503043093&fm=79&app=86&f=JPEG?w=1280&h=853'},
{id: 'c2', type: 'courseware', label: '待定课件12', updated: '2020 14:00', status: 1, thumbnail: 'http://t8.baidu.com/it/u=1484500186,1503043093&fm=79&app=86&f=JPEG?w=1280&h=853'},
],
},
]
];
</script>

datePicker

  1. 如果是时间范围选择器 清空情况的时候会把数据改为null. 导致解构赋值的时候报错 [start, end] = timeRange
    <!–
  2. 下面是无用的。其实value-format 是可以实现的
    <!–
    不能设置value-format,使用默认。
    使用format指定输入框的格式;使用value-format指定绑定值的格式。
knowledge is no pay,reward is kindness
0%